import {MetadataCenter} from "./MetadataCenter";
import {Key, MetadataValue} from "./common";

export class AnnotationFactory {
	public static readonly METADATA_CENTER = "MetadataCenter";

	/**
	 * @private
	 * @param klass 构造函数 (在ts的世界里可以当作是 class)
	 */
	private static getManager(klass: Function): MetadataCenter {
		if (!Reflect.getMetadata(this.METADATA_CENTER, klass)) {
			Reflect.defineMetadata(this.METADATA_CENTER, new MetadataCenter(klass), klass)
		}
		return Reflect.getMetadata(this.METADATA_CENTER, klass) as MetadataCenter;
	}

	/**
	 * 类的注解
	 * @param affiliatedMetadataDomain
	 * @param metadataKey
	 * @param metadataValue
	 */
	public static classAnnotation(
		affiliatedMetadataDomain: Key,
		metadataKey: Key,
		metadataValue?: MetadataValue
	): ClassDecorator {
		return (klass) => {
			this.getManager(klass)
				.classMetadataManager
				.add(affiliatedMetadataDomain, klass.name, metadataKey, metadataValue);
		};
	}

	/**
	 * 属性的注解
	 * @param affiliatedMetadataDomain
	 * @param metadataKey
	 * @param metadataValue
	 */
	public static propertyAnnotation(
		affiliatedMetadataDomain: Key,
		metadataKey: Key,
		metadataValue?: MetadataValue
	): PropertyDecorator {
		return (instance, propertyKey) => {
			const {constructor: klass} = instance;
			this.getManager(klass)
				.propertyMetadataManager
				.add(affiliatedMetadataDomain, propertyKey, metadataKey, metadataValue);
		};
	}
}
